/**
 * Copyright (c) 2023 murenchao
 * taomu is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *       http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package cool.taomu.box.storage.lmdb

import cool.taomu.box.storage.inter.IStorage
import java.nio.ByteBuffer
import java.nio.charset.StandardCharsets
import javax.inject.Inject
import org.lmdbjava.Cursor
import org.lmdbjava.GetOp

import static org.lmdbjava.DbiFlags.MDB_CREATE

class LmdbUtils implements IStorage {
	
	@Inject
	LmdbDataSource ds

	override put(String identifier, String key, byte[] value) {
		var env = ds.env;
		var db = env.openDbi(identifier, MDB_CREATE);
		try(var txn = env.txnWrite) {
			try(var Cursor<ByteBuffer> c = db.openCursor(txn)) {
				var keyByte = key.getBytes(StandardCharsets.UTF_8);
				var ByteBuffer keyBuf = ByteBuffer.allocateDirect(keyByte.length);
				keyBuf.put(keyByte).flip
				var ByteBuffer valueBuf = ByteBuffer.allocateDirect(value.length);
				valueBuf.put(value).flip
				c.put(keyBuf, valueBuf);
			}
			txn.commit;
		}
		return 1;
	}

	override get(String identifier, String key) {
		var env = ds.env;
		var db = env.openDbi(identifier);
		try(var txn = env.txnRead) {
			var ByteBuffer buffer = null;
			try(var c = db.openCursor(txn)) {
				var keyByte = key.getBytes(StandardCharsets.UTF_8);
				var ByteBuffer keyBuf = ByteBuffer.allocateDirect(keyByte.length);
				keyBuf.put(keyByte).flip
				if (c.get(keyBuf, GetOp.MDB_SET_KEY)) {
					buffer = c.^val();
					if (buffer !== null) {
						var int length = buffer.limit() + buffer.position();
						var byte[] bytes = newByteArrayOfSize(length);
						buffer.get(bytes);
						return bytes;
					}
				}
			}
		}
		return null;
	}

	override remove(String identifier, String key) {
		var env = ds.env;
		var db = env.openDbi(identifier);
		try(var txn = env.txnWrite) {
			try(var c = db.openCursor(txn)) {
				var keyByte = key.getBytes(StandardCharsets.UTF_8);
				var ByteBuffer keyBuf = ByteBuffer.allocate(keyByte.length);
				keyBuf.put(keyByte).flip
				var ByteBuffer valueBuf = ByteBuffer.allocate(0);
				c.put(keyBuf, valueBuf);
				c.delete();
			}
			txn.commit
		}
	}

	override clear(String identifier) {
		throw new UnsupportedOperationException("TODO: auto-generated method stub")
	}

}
